package com.dingdang.filter;

import com.alibaba.fastjson.JSONObject;
import com.dingdang.data.Result;
import com.dingdang.em.ResultEnum;
import com.dingdang.utils.JwtUtil;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Component
public class LoginFilter extends ZuulFilter {
    @Resource
    private JwtUtil jwtUtil;

    private static final List<String> ignoreUrl= new ArrayList<>();
//  要放过的数据
    static {
            ignoreUrl.add("/login/api/login/getCode");
//        ignoreUrl.add("/orderPath/order");
        ignoreUrl.add("/login/api/login/getCode");
        ignoreUrl.add("/login/api/login/loginCheck");
        ignoreUrl.add("/reserve/api/reserve/");
        ignoreUrl.add("/reserve/api/reserve/notifyUrl");
        ignoreUrl.add("/reserve/api/reserve/returnUrl");
        ignoreUrl.add("/login/api/login");
        ignoreUrl.add("/hot/addHot");
    }
    /**
     * 配置过滤类型，有四种不同生命周期的过滤器类型
     * 1. pre：路由之前
     * 2. routing：路由之时
     * 3. post：路由之后
     * 4. error：发送错误调用
     * @return
     */
    @Override
    public String filterType() {

        return FilterConstants.PRE_TYPE;
    }

    //过滤的顺序 数字越小顺序越靠前，过滤的顺序  我们网关可以写多个过滤器,那个过滤器的方法数值越小越先执行
    @Override
    public int filterOrder() {
        return 1;
    }
//    过滤
    @Override
    public boolean shouldFilter() {
        //        获取上下文
        RequestContext currentContext = RequestContext.getCurrentContext();
//        判断上一层是否拦截
        if (!currentContext.sendZuulResponse()){
            return false;
        }

//        获取域对象
        HttpServletRequest request = currentContext.getRequest();
//        获取路径
        String requestURI = request.getRequestURI();
//        放过的路径
        if (ignoreUrl.contains(requestURI)){
            return false;
        }
        return true;
    }

    @Override
        public Object run() throws ZuulException {

        //        获取当前线程请求的上下文
        RequestContext currentContext = RequestContext.getCurrentContext();
//        获取request域对象\
        HttpServletRequest request = currentContext.getRequest();
//        通过请求头获取token
        String authToken = request.getHeader("authToken");
//        ||redisTemplate.boundValueOps(authToken).get()==null
        String subject = null;
        if (StringUtils.isEmpty(authToken)){
            authToken(currentContext);
        }else {
            try {
                Claims claims = jwtUtil.parseJwt(authToken);
                String id = claims.getId();
                subject = claims.getSubject();
                
            } catch (Exception e) {
                authToken(currentContext);
            }
        }
        return subject;
    }

    //  抽取方法
    public void authToken(RequestContext currentContext){
        //设置响应域对象
        currentContext.setSendZuulResponse(false);
        currentContext.setResponseStatusCode(400);
        //获取response
        HttpServletResponse response = currentContext.getResponse();
        try {
            response.setContentType("text/html;charset=utf-8");
            Result result = Result.response(ResultEnum.NOLOGIN);
            response.getWriter().write(JSONObject.toJSONString(result));
        } catch (IOException e) {
            e.printStackTrace();

        }
    }
}
